En C++, toda expresión da como resultado un lvalue o un rvalue. Esta distinción define si una expresión hace referencia a la identidad (dónde está) o su valor (qué contiene).
1. Identidad frente a Contenidos
Un lvalue (valor de localización) representa un objeto con una dirección de memoria persistente. Piénselo como una caja etiquetada en la RAM. Por el contrario, un rvalue (valor de lectura) es transitorio; representa un resultado temporal o una literal que no tiene una dirección accesible para el programador.
2. Transiciones Funcionales
Mientras que un lvalue puede actuar como un rvalue (el compilador simplemente obtiene el valor dentro de la caja), lo contrario está prohibido. No puedes usar un rvalue donde se requiere un lvalue—por ejemplo, no puedes obtener la dirección de un número literal como &42 porque carece de una identidad persistente.
$$ \text{Lvalue} \xrightarrow{\text{Conversión}} \text{Rvalue} \quad (\text{Permitido}) $$
$$ \text{Rvalue} \xrightarrow{\text{Asignación}} \text{Lvalue} \quad (\text{Prohibido}) $$